#version 300 es
precision highp float;
precision highp int;

uniform sampler2D diffuse;

in vec2 v_st;

out vec4 color;

vec4 catmullRom(in vec4 A, in vec4 B, in vec4 C, in vec4 D, in float s)
{
    mat4 catmullRomMatrix = mat4(
        vec4(-1.0, 2.0,-1.0, 0.0),
        vec4( 3.0,-5.0, 0.0, 2.0),
        vec4(-3.0, 4.0, 1.0, 0.0),
        vec4( 1.0,-1.0, 0.0, 0.0));

    vec4 expo = vec4(s * s * s, s * s, s, 1.0);

    return 0.5 * expo * catmullRomMatrix * mat4(
        A[0], B[0], C[0], D[0],
        A[1], B[1], C[1], D[1],
        A[2], B[2], C[2], D[2],
        A[3], B[3], C[3], D[3]);
}

vec4 textureCatmullrom(in sampler2D sampler, in vec2 st)
{
    ivec2 size = textureSize(sampler, 0);
    ivec2 texelCoord = ivec2(vec2(size) * st);

    vec4 texel00 = texelFetchOffset(sampler, texelCoord, 0, ivec2(-1,-1));
    vec4 texel10 = texelFetchOffset(sampler, texelCoord, 0, ivec2( 0,-1));
    vec4 texel20 = texelFetchOffset(sampler, texelCoord, 0, ivec2( 1,-1));
    vec4 texel30 = texelFetchOffset(sampler, texelCoord, 0, ivec2( 2,-1));

    vec4 texel01 = texelFetchOffset(sampler, texelCoord, 0, ivec2(-1, 0));
    vec4 texel11 = texelFetchOffset(sampler, texelCoord, 0, ivec2( 0, 0));
    vec4 texel21 = texelFetchOffset(sampler, texelCoord, 0, ivec2( 1, 0));
    vec4 texel31 = texelFetchOffset(sampler, texelCoord, 0, ivec2( 2, 0));

    vec4 texel02 = texelFetchOffset(sampler, texelCoord, 0, ivec2(-1, 1));
    vec4 texel12 = texelFetchOffset(sampler, texelCoord, 0, ivec2( 0, 1));
    vec4 texel22 = texelFetchOffset(sampler, texelCoord, 0, ivec2( 1, 1));
    vec4 texel32 = texelFetchOffset(sampler, texelCoord, 0, ivec2( 2, 1));

    vec4 texel03 = texelFetchOffset(sampler, texelCoord, 0, ivec2(-1, 2));
    vec4 texel13 = texelFetchOffset(sampler, texelCoord, 0, ivec2( 0, 2));
    vec4 texel23 = texelFetchOffset(sampler, texelCoord, 0, ivec2( 1, 2));
    vec4 texel33 = texelFetchOffset(sampler, texelCoord, 0, ivec2( 2, 2));

    vec2 splineCoord = fract(vec2(size * texelCoord));

    vec4 row0 = catmullRom(texel00, texel10, texel20, texel30, splineCoord.x);
    vec4 row1 = catmullRom(texel01, texel11, texel21, texel31, splineCoord.x);
    vec4 row2 = catmullRom(texel02, texel12, texel22, texel32, splineCoord.x);
    vec4 row3 = catmullRom(texel03, texel13, texel23, texel33, splineCoord.x);

    return catmullRom(row0, row1, row2, row3, splineCoord.y);
}

void main()
{
    color = textureCatmullrom(diffuse, v_st);
}